/*
 * @Author: quit
 * @Date: 2023-03-07 17:13:07
 * @LastEditTime: 2023-03-08 02:23:10
 * @Descripttion: 在TS中声明变量会与JS有些许不同
 * @notice: 在TS中推荐使用 const \ let 替代 var 来声明
 * var 只存在 函数作用域与全局作用域
 * let \ const 存在块级作用域
 * let 声明的变量使用的是词法作用域,不存在变量提升
 */

/**
 * @description: 变量声明提升
 * 多次声明同一变量
 */
// function fun(flag: boolean): any {
//     if (flag) {
//         var i: number = 0;
//     }
//     return i;
// }
// console.log(fun(true)); // 0
// console.log(fun(false)); // undefinde

// function fun(flag: boolean): any {
//     if (flag) {
//         let i: number = 0;
//     }
//     return i; // 这里因为作用域的问题无法访问变量
// }

// function fun(flag: boolean): any {
//     let i: number;
//     if (flag) {
//         i = 0;
//     }
//     return i;
// }
// console.log(fun(true)); // 0
// console.log(fun(false)); // undefinde

// 变量与作用域息息相关
function fun(flag: boolean): any {
    let i: number;
    if (flag) {
        let i: number = 0;
    }
    return i;
}
console.log(fun(true)); // undefinde
console.log(fun(false)); // undefinde

// for 循环
// for (var i: number = 0; i < 3; i++) {
//     setTimeout(() => {
//         console.log(i); // 5 5 5,因为i在声明时是全局变量在执行时,异步任务后执行,但是i的++行为先作为同步任务执行完毕所以都是5
//     }, i * 1000);
// }

// for (var i: number = 0; i < 3; i++) {
//     (function (i) { // 在这个立即执行函数中 每一次循环都会将当前i值进行保留在自己的作用域中进行使用(作为了立即执行函数的参数传递)
//         setTimeout(function () {
//             console.log(i);
//         }, i * 200);
//     })(i);
// }
// let 和 const 声明的变量有块级作用域
for (let i: number = 0; i < 4; i++) {
    setTimeout(function () {
        console.log(i);
    }, i * 200);
}

/**
 * @description: const 声明变量
 * const 声明的是常量
 */
let l1: number = 1;
l1 = 2;
const _c: number = 3;
// _c = 4; 由const声明的变量无法修改
const obj: any = {
    name: 'jack'
};
// 这样是无法改变的
// obj = {
//     name: 'lucy'
// };
// 可以使用;这里是修改的obj里面的值,值都是存在堆里面,并没有将obj存在于栈内的地址修改
obj.name = 'lucy';
